package com.vitogiovanni.tobook.entity;

import java.util.HashMap;
import java.util.List;

import javax.annotation.Nullable;
import javax.inject.Named;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.persistence.EntityNotFoundException;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiMethod.HttpMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.response.CollectionResponse;
import com.google.appengine.api.datastore.Cursor;
import com.google.appengine.datanucleus.query.JDOCursorHelper;

@Api(name = "menuendpoint", namespace = @ApiNamespace(ownerDomain = "vitogiovanni.com", ownerName = "vitogiovanni.com", packagePath = "tobook.entity"))
public class MenuEndpoint {

	/**
	 * This method lists all the entities inserted in datastore.
	 * It uses HTTP GET method and paging support.
	 *
	 * @return A CollectionResponse class containing the list of all entities
	 * persisted and a cursor to the next page.
	 */
	@SuppressWarnings({ "unchecked", "unused" })
	@ApiMethod(name = "listMenu")
	public CollectionResponse<Menu> listMenu(
			@Nullable @Named("cursor") String cursorString,
			@Nullable @Named("limit") Integer limit) {

		PersistenceManager mgr = null;
		Cursor cursor = null;
		List<Menu> execute = null;

		try {
			mgr = getPersistenceManager();
			Query query = mgr.newQuery(Menu.class);
			if (cursorString != null && cursorString != "") {
				cursor = Cursor.fromWebSafeString(cursorString);
				HashMap<String, Object> extensionMap = new HashMap<String, Object>();
				extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, cursor);
				query.setExtensions(extensionMap);
			}

			if (limit != null) {
				query.setRange(0, limit);
			}

			execute = (List<Menu>) query.execute();
			cursor = JDOCursorHelper.getCursor(execute);
			if (cursor != null)
				cursorString = cursor.toWebSafeString();

			// Tight loop for fetching all entities from datastore and accomodate
			// for lazy fetch.
			for (Menu obj : execute)
				;
		} finally {
			mgr.close();
		}

		return CollectionResponse.<Menu> builder().setItems(execute)
				.setNextPageToken(cursorString).build();
	}

	/**
	 * This method gets the entity having primary key id. It uses HTTP GET method.
	 *
	 * @param id the primary key of the java bean.
	 * @return The entity with primary key id.
	 */
	@ApiMethod(name = "getMenu")
	public Menu getMenu(@Named("id") Long id) {
		PersistenceManager mgr = getPersistenceManager();
		Menu menu = null;
		try {
			menu = mgr.getObjectById(Menu.class, id);
			List<ElementoMenu> listaElementi = menu.getElementiMenu();
			
			// Tight loop for fetching all entities from datastore and
			// accomodate
			// for lazy fetch.
			for (ElementoMenu obj : listaElementi){
				obj.getCategoriaElemento();
				obj.getTipoElemento();
			}
				
		} finally {
			mgr.close();
		}
		return menu;
	}
	
	@ApiMethod(name = "getMenuDetachable", path="get_menu_detachable")
	public Menu getMenuDetachable(@Named("id") Long id) {
		PersistenceManager mgr = getPersistenceManager();
		Menu temp=null, menu = null;
		try {
			temp = mgr.getObjectById(Menu.class, id);
			menu = mgr.detachCopy(temp);
			//List<ElementoMenu> listaElementi = menu.getElementiMenu();
			
			
			// Tight loop for fetching all entities from datastore and
			// accomodate
			// for lazy fetch.
			/*for (ElementoMenu obj : listaElementi){
				obj.getCategoriaElemento();
				obj.getTipoElemento();
			}*/
				
		} finally {
			mgr.close();
		}
		return menu;
	}
	
	

	/**
	 * This inserts a new entity into App Engine datastore. If the entity already
	 * exists in the datastore, an exception is thrown.
	 * It uses HTTP POST method.
	 *
	 * @param menu the entity to be inserted.
	 * @return The inserted entity.
	 */
	@ApiMethod(name = "insertMenu")
	public Menu insertMenu(Menu menu) {
		PersistenceManager mgr = getPersistenceManager();
		try {
			/*if (containsMenu(menu)) {
				throw new EntityExistsException("Object already exists");
			}*/
			mgr.makePersistent(menu);
		} finally {
			mgr.close();
		}
		return menu;
	}

	/**
	 * This method is used for updating an existing entity. If the entity does not
	 * exist in the datastore, an exception is thrown.
	 * It uses HTTP PUT method.
	 *
	 * @param menu the entity to be updated.
	 * @return The updated entity.
	 */
	@ApiMethod(name = "updateMenu")
	public Menu updateMenu(Menu menu) {
		PersistenceManager mgr = getPersistenceManager();
		try {
			if (!containsMenu(menu)) {
				throw new EntityNotFoundException("Object does not exist");
			}
			mgr.makePersistent(menu);
		} finally {
			mgr.close();
		}
		return menu;
	}

	/**
	 * This method removes the entity with primary key id.
	 * It uses HTTP DELETE method.
	 *
	 * @param id the primary key of the entity to be deleted.
	 */
	@ApiMethod(name = "removeMenu")
	public void removeMenu(@Named("id") Long id) {
		PersistenceManager mgr = getPersistenceManager();
		try {
			Menu menu = mgr.getObjectById(Menu.class, id);
			mgr.deletePersistent(menu);
		} finally {
			mgr.close();
		}
	}

	/**
	 * This method gets the entity Menu related to the Locale having primary key id. It uses HTTP GET method.
	 * The Menu has already his ElementoMenu entities loaded.
	 * @param id the primary key of the java bean.
	 * @return The entity with primary key id.
	 */
	@ApiMethod(name = "getMenuLocaleFull", path="get_menu_locale_full")
	public Menu getMenuLocaleFull(@Named("id") Long id) {
		PersistenceManager mgr = getPersistenceManager();
		Locale locale = null;
		Menu menu = null;
		try {
			locale = mgr.getObjectById(Locale.class, id);
			menu = locale.getMenu();
			menu.getElementiMenu();
		} finally {
			mgr.close();
		}
		return menu;
	}
	
	
	
	private boolean containsMenu(Menu menu) {
		PersistenceManager mgr = getPersistenceManager();
		boolean contains = true;
		try {
			mgr.getObjectById(Menu.class, menu.getId());
		} catch (javax.jdo.JDOObjectNotFoundException ex) {
			contains = false;
		} finally {
			mgr.close();
		}
		return contains;
	}

	private static PersistenceManager getPersistenceManager() {
		return PMF.get().getPersistenceManager();
	}
	
	@ApiMethod(name = "addElementoMenu", path="add_elemento_menu", httpMethod=HttpMethod.POST)
	public void addElementoMenu(@Named("id")Long id, ElementoMenu elemMenu)
	{
		PersistenceManager mgr = getPersistenceManager();
		Menu menu = null;
		try {
			menu = mgr.getObjectById(Menu.class, id);
			List<ElementoMenu> listaElementiMenu = menu.getElementiMenu();
			elemMenu.setMenu(menu);
			listaElementiMenu.add(elemMenu);
			
		} finally {
			mgr.close();
		}
	}
	
	@SuppressWarnings({ "unchecked", "finally" })
	@ApiMethod(name = "findByNome", path="find_menu_by_nome", httpMethod=HttpMethod.GET)
	public Menu findByNome(@Named("nome") String nome) {

		//Logger log = Logger.getLogger(GestoreEndpoint.class.getName());

		//log.severe("An informational message.");
		PersistenceManager mgr = getPersistenceManager();
		List<Menu> menu = null;
		// List<Gestore> gestore = new List<Gestore>();
		//log.severe("An informational message after gestore.");
		try {
			Query query = mgr.newQuery(Menu.class);
			query.setFilter("nome == thatNome");
			query.declareParameters("String thatNome");
			menu = (List<Menu>) query.execute(nome);
			//log.severe("An informational message after query."
					//+ gestore.get(0).getCognome());
			List<ElementoMenu> listaElementi = menu.get(0).getElementiMenu();
			
			// Tight loop for fetching all entities from datastore and
			// accomodate
			// for lazy fetch.
			for (ElementoMenu obj : listaElementi){
				obj.getCategoriaElemento();
				obj.getTipoElemento();
			}
		} finally {
			mgr.close();
			return menu.get(0);
		}

	}
	
	
}
